package cc.rengu.igas.bsps.core.service.trans;

import cc.rengu.igas.bsps.common.constant.BspsAppParamConstant;
import cc.rengu.igas.bsps.common.dao.*;
import cc.rengu.igas.bsps.common.dao.impl.*;
import cc.rengu.igas.bsps.common.entity.*;
import cc.rengu.igas.bsps.common.enums.*;
import cc.rengu.igas.bsps.core.model.UserSessionInfo;
import cc.rengu.igas.bsps.core.service.base.ManageService;
import cc.rengu.igas.bsps.facade.base.Header;
import cc.rengu.igas.bsps.facade.bean.MchntBindInfoBean;
import cc.rengu.igas.bsps.facade.bean.PrivilegeInfoBean;
import cc.rengu.igas.bsps.facade.request.LoginOrderStatusQueryRequest;
import cc.rengu.igas.bsps.facade.response.LoginOrderStatusQueryResponse;
import cc.rengu.igas.share.common.util.SensitiveDataUtil;
import cc.rengu.igas.share.core.model.GroupMchntInfo;
import cc.rengu.igas.share.core.realize.MchntService;
import cc.rengu.igas.share.core.realize.impl.MchntServiceImpl;
import cc.rengu.oltp.service.common.constant.AppConfigConstant;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.dao.UserOrderInfoMapper;
import cc.rengu.oltp.service.common.dao.impl.UserOrderInfoMapperImpl;
import cc.rengu.oltp.service.common.entity.SysParam;
import cc.rengu.oltp.service.common.entity.UserOrderInfo;
import cc.rengu.oltp.service.common.enums.OrderStatusEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.model.BizResponse;
import cc.rengu.oltp.service.realize.SysParamService;
import cc.rengu.oltp.service.realize.impl.SysParamServiceImpl;
import cc.rengu.oltp.utility.util.*;
import com.alibaba.fastjson.JSON;
import org.apache.commons.codec.binary.Base64;
import org.springframework.util.CollectionUtils;

import java.io.ByteArrayOutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

import static com.alibaba.fastjson.JSON.toJSONString;

/**
 * @author zhangxuran
 * @date 2020/04/15
 */
public class LoginOrderStatusQueryService extends ManageService {

    @Override
    protected Object bizBeforeCust() throws Exception {
        LoginOrderStatusQueryRequest loginOrderStatusQueryRequest = new LoginOrderStatusQueryRequest();
        ConvertUtil.convertOutput(loginOrderStatusQueryRequest);
        return loginOrderStatusQueryRequest;
    }

    @Override
    protected BizResponse bizProcessCust(Object request) throws Exception {
        LoginOrderStatusQueryRequest loginOrderStatusQueryRequest = (LoginOrderStatusQueryRequest) request;
        LoginOrderStatusQueryResponse loginOrderStatusQueryResponse = new LoginOrderStatusQueryResponse();
        /*获取请求参数：法人行号，登录订单号，交易流水号*/
        String instId = loginOrderStatusQueryRequest.getHeader().getInstId();
        String loginOrderId = loginOrderStatusQueryRequest.getLoginOrderId();
        String sessionId = loginOrderStatusQueryRequest.getHeader().getSession();
        String channelId = loginOrderStatusQueryRequest.getHeader().getChanlId();
        if (StringUtil.isEmptyOrNull(loginOrderId)) {
            rglog.error("登录订单查询交易必填性校验失败！");
            throw new BizException(RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespCode(), RespCodeEnum.MSG_VALID_CHECK_ERROR.getRespDesc());
        }
        /*查询用户登录订单信息*/
        UserOrderInfoMapper userOrderInfoMapper = new UserOrderInfoMapperImpl();
        UserOrderInfo userOrderInfo = userOrderInfoMapper.selectUserOrderInfoByMchntOrderId(instId, loginOrderId, loginOrderStatusQueryRequest.getHeader().getSrcSysId(), loginOrderStatusQueryRequest.getHeader().getChanlId());
        if (null == userOrderInfo) {
            rglog.error("查询用户登录订单失败！");
            throw new BizException(RespCodeEnum.GET_QRCODE_INFO_ERROR.getRespCode(), RespCodeEnum.GET_QRCODE_INFO_ERROR.getRespDesc());
        }
        /*登录订单过期判断*/
        if (OrderStatusEnum.INVALID.getStatus().equals(userOrderInfo.getOrderStatus()) || DateUtil.compareTime(DateUtil.getCurrentDateTime("yyyyMMddHHmmss"), userOrderInfo.getOrderExpiryTime(), "yyyyMMddHHmmss") > 0) {
            rglog.error("登录二维码订单过期！");
            throw new BizException(RespCodeEnum.USER_LOGIN_QRCODE_ERROR.getRespCode(), RespCodeEnum.USER_LOGIN_QRCODE_ERROR.getRespDesc());
        }
        /*登录订单完成，查询绑定用户权限*/
        if (OrderStatusEnum.FINISH.getStatus().equals(userOrderInfo.getOrderStatus())) {
            /*根据用户标识查询用户信息及权限信息*/
            BspsUserInfoMapper bspsUserInfoMapper = new BspsUserInfoMapperImpl();
            UserInfo userInfo = bspsUserInfoMapper.selectBspsUserInfoByUserId(instId, userOrderInfo.getUserId());
            if (null == userInfo) {
                rglog.error("查询用户信息失败！");
                throw new BizException(RespCodeEnum.GET_USER_INFO_ERROR.getRespCode(), RespCodeEnum.GET_USER_INFO_ERROR.getRespDesc());
            }
            /*根据用户查询绑定商户信息*/
            List<MchntBindInfoBean> mchntBindInfoList = new ArrayList<>();
            BspsMchntBindInfoMapper bspsMchntBindInfoMapper = new BspsMchntBindInfoMapperImpl();
            List<MchntBindInfo> mchntBindInfos = bspsMchntBindInfoMapper.selectBspsMchntBindInfoListByUserId(instId, userInfo.getUserId());
            if (!CollectionUtils.isEmpty(mchntBindInfos)) {
                mchntBindInfos.forEach(item -> convMchntBindInfo(item, mchntBindInfoList, channelId));
            }
            loginOrderStatusQueryResponse.setMchntBindInfoBeanList(mchntBindInfoList);

            /*新增用户登录信息*/
            BspsUserLoginInfoMapper bspsUserLoginInfoMapper = new BspsUserLoginInfoMapperImpl();
            UserLoginInfo userLoginInfo = new UserLoginInfo();
            /*法人行赋值*/
            userLoginInfo.setInstId(instId);
            /*登录方式赋值*/
            userLoginInfo.setLoginType(BspsLoginTypeEnum.OPEN_ID.getLoginType());
            /*用户标识赋值*/
            userLoginInfo.setUserId(userOrderInfo.getUserId());
            /*登录时间赋值*/
            userLoginInfo.setLoginTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
            /*最后操作时间赋值*/
            userLoginInfo.setLastOprTime(DateUtil.getCurrentDateTime("yyyy-MM-dd HH:mm:ss.SSS"));
            /*登录状态赋值*/
            userLoginInfo.setLoginStatus(BspsLogInOutOprEnum.LOGIN.getOprType().substring(1));
            /*sessionId赋值*/
            userLoginInfo.setSessionId(loginOrderStatusQueryRequest.getHeader().getSession());

            XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
            String dbPoolName = XmlConfigUtil.getXmlConfigCacheKeyValue(AppConfigConstant.DATABASE_CONF_NODE, AppConfigConstant.OLTP_POOL_NAME);
            String corporation = xmlTreeUtil.getXmlTreeStringValue(AppParamConstant.CORPORATION);
            if (null != corporation && !corporation.isEmpty()) {
                String dbPoolCashNode = corporation.trim() + AppParamConstant.DATABASE_CONF_NODE;
                dbPoolName = XmlConfigUtil.getXmlConfigCacheKeyValue(dbPoolCashNode, AppConfigConstant.OLTP_POOL_NAME);
            }
            DbsUtil dbsUtil = new DbsUtil(dbPoolName);
            dbsUtil.dbsBeginTransaction();

            /*新增用户登录信息*/
            int iReturnCode = bspsUserLoginInfoMapper.insertBspsUserLoginInfo(userLoginInfo);
            if (0 != iReturnCode) {
                dbsUtil.dbsEndTransaction(false);
                rglog.error("用户登录信息新增失败！");
                throw new BizException(RespCodeEnum.REGISTER_USER_LOGIN_INFO_ERROR.getRespCode(), RespCodeEnum.REGISTER_USER_LOGIN_INFO_ERROR.getRespDesc());
            }
            dbsUtil.dbsEndTransaction(true);

            UserSessionInfo keySessionInfo = JSON.parseObject(RedisUtil.onceGet(sessionId), UserSessionInfo.class);
            if (null == keySessionInfo) {
                rglog.error("session超时");
                throw new BizException(RespCodeEnum.USER_NOT_LOGIN_OR_SESSION_IS_EXPIRED.getRespCode(), RespCodeEnum.USER_NOT_LOGIN_OR_SESSION_IS_EXPIRED.getRespDesc());
            }
            keySessionInfo.setUserId(userInfo.getUserId());
            RedisUtil.onceSet(sessionId, toJSONString(keySessionInfo), BspsAppParamConstant.SESSION_EFFECTIVE_TIME);
            //生成新的会话id
            String newSessionId = RandomUtil.getUUID();
            UserSessionInfo userSessionInfo = new UserSessionInfo();
            userSessionInfo.setUserId(userInfo.getUserId());
            userSessionInfo.setSignatureKey(keySessionInfo.getSignatureKey());
            userSessionInfo.setSensitiveKey(keySessionInfo.getSensitiveKey());
            RedisUtil.onceSet(newSessionId, toJSONString(userSessionInfo), BspsAppParamConstant.SESSION_EFFECTIVE_TIME);
            Header header = loginOrderStatusQueryRequest.getHeader();
            header.setSession(newSessionId);
            loginOrderStatusQueryResponse.setHeader(header);

            if (!StringUtil.isEmptyOrNull(userInfo.getTransPassword())) {
                loginOrderStatusQueryResponse.setVerifyFlag("Y");
            } else {
                loginOrderStatusQueryResponse.setVerifyFlag("N");
            }

            /*用户标识赋值*/
            loginOrderStatusQueryResponse.setUserId(userInfo.getUserId());
            /*用户昵称赋值*/
            loginOrderStatusQueryResponse.setNickName(userInfo.getNickName());
            /*用户性别赋值*/
            loginOrderStatusQueryResponse.setUserSex(userInfo.getUserSex());
            /*用户电子邮箱赋值*/
            loginOrderStatusQueryResponse.setEmail(userInfo.getEmail());
            loginOrderStatusQueryResponse.setUserLoginId(userInfo.getUserLoginId());
            /*用户头像赋值*/
            if (!StringUtil.isEmptyOrNull(userInfo.getUserImagePath())) {
                loginOrderStatusQueryResponse.setUserImagePath(Base64.encodeBase64String(userInfo.getUserImagePath().getBytes()));
            }
            loginOrderStatusQueryResponse.setUserSex(userInfo.getUserSex());
            if (!StringUtil.isEmptyOrNull(userInfo.getMobileNo())) {
                loginOrderStatusQueryResponse.setPhoneNo(SensitiveDataUtil.desensitization("1", userInfo.getMobileNo()).split("\\|")[0]);
            }

        }
        /* 按照接口转换基础产品信息并响应给请求方 */
        BizResponse<LoginOrderStatusQueryResponse> bizResponse = new BizResponse<>();
        bizResponse.setRspSysId(AppParamConstant.SYS_ID);
        bizResponse.setRespCode(RespCodeEnum.TRANS_SUCCESS.getRespCode());
        bizResponse.setRespDesc(RespCodeEnum.TRANS_SUCCESS.getRespDesc());
        bizResponse.setResult(loginOrderStatusQueryResponse);
        return bizResponse;
    }

    /*用户绑定信息转换
     * mchntBindInfo 用户绑定商户信息
     * */
    private void convMchntBindInfo(MchntBindInfo mchntBindInfo, List<MchntBindInfoBean> mchntBindInfoList, String channelId) {
        try {
            MchntBindInfoBean mchntBindInfoBean = new MchntBindInfoBean();
            /*商户号赋值*/
            mchntBindInfoBean.setMchntNo(mchntBindInfo.getMchntNo());
            /*商户连锁号赋值*/
            mchntBindInfoBean.setChainMchntNo(mchntBindInfo.getChainMchntNo());
            /*绑定状态赋值*/
            mchntBindInfoBean.setBindStatus(mchntBindInfo.getBindStatus());
            /*绑定时间赋值*/
            mchntBindInfoBean.setBindTime(mchntBindInfo.getBindDate() + " " + mchntBindInfo.getBindTime());
            /*用户角色赋值*/
            mchntBindInfoBean.setBindUserRole(mchntBindInfo.getBindUserRole());
            /*商户类型赋值*/
            mchntBindInfoBean.setMchntType(mchntBindInfo.getBindMchntType());
            /*商户名称赋值*/
            BspsMchntBaseInfoMapper bspsMchntBaseInfoMapper = new BspsMchntBaseInfoMapperImpl();
            BspsAgentInfoMapper bspsAgentInfoMapper = new BspsAgentInfoMapperImpl();
            BspsPlatformMchntInfoMapper bspsPlatformMchntInfoMapper = new BspsPlatformMchntInfoMapperImpl();
            if (BspsMchntTypeEnum.AGENT_MCHNT.getMchntType().equals(mchntBindInfo.getBindMchntType())) {
                AgentInfo agentInfo = bspsAgentInfoMapper.selectBspsAgentInfoByInstIdAndAgentCode(mchntBindInfo.getInstId(), mchntBindInfo.getMchntNo());
                if (null != agentInfo) {
                    mchntBindInfoBean.setMchntName(agentInfo.getAgentName());
                }
            } else if (BspsMchntTypeEnum.PLAT_MCHNT.getMchntType().equals(mchntBindInfo.getBindMchntType())) {
                PlatformMchntInfo platformMchntInfo = bspsPlatformMchntInfoMapper.selectBspsPlatformMchntInfoByInstIdAndMchntNo(mchntBindInfo.getInstId(), mchntBindInfo.getMchntNo());
                if (null != platformMchntInfo) {
                    mchntBindInfoBean.setMchntName(platformMchntInfo.getPlatMchntName());
                }
            } else if (BspsMchntTypeEnum.GROUP_MCHNT.getMchntType().equals(mchntBindInfo.getBindMchntType())) {
                MchntService mchntService = new MchntServiceImpl();
                GroupMchntInfo groupMchntInfo = mchntService.getGroupMchntInfo(mchntBindInfo.getInstId(), mchntBindInfo.getMchntNo());
                if (null != groupMchntInfo) {
                    mchntBindInfoBean.setMchntName(groupMchntInfo.getGroupMchntName());
                }
            } else {
                MchntBaseInfo mchntBaseInfo = bspsMchntBaseInfoMapper.selectBspsMchntBaseInfoByPrimaryKey(mchntBindInfo.getInstId(), mchntBindInfo.getMchntNo());
                if (null != mchntBaseInfo) {
                    mchntBindInfoBean.setMchntName(mchntBaseInfo.getMchntName());
                    mchntBindInfoBean.setCashWithdrawalFlag(mchntBaseInfo.getCashWithdrawalFlag());
                }
            }

            /*退款权限-法人、店长都有权限,白名单的收银员有权限*/
            if (((BspsUserRoleTypeEnum.MCHNT_ARTIF.getRoleType().equals(mchntBindInfo.getBindUserRole()))
                    || (BspsUserRoleTypeEnum.MCHNT_MANAGER.getRoleType().equals(mchntBindInfo.getBindUserRole())))) {
                rglog.info("法人、店长登录");
                //有退款权限
                mchntBindInfoBean.setRefundFlag(AppParamConstant.YES);
            } else {
                rglog.info("非法人、店长登录");
                //校验白名单收银员退款权限,null/NO为无权限
                SysParamService sysParamService = new SysParamServiceImpl();
                SysParam sysParam = sysParamService.getSysParamInfo(mchntBindInfo.getInstId(), BspsAppParamConstant.BSPS_REFUND_MERCH, mchntBindInfo.getMchntNo());
                if (sysParam == null) {
                    rglog.info("非白名单商户");
                    mchntBindInfoBean.setRefundFlag(AppParamConstant.NO);
                } else if (AppParamConstant.YES.equals(sysParam.getParamValue())) {
                    rglog.info("白名单商户");
                    mchntBindInfoBean.setRefundFlag(AppParamConstant.YES);
                } else {
                    rglog.info("非白名单商户");
                    mchntBindInfoBean.setRefundFlag(AppParamConstant.NO);
                }
            }

            /*根据用户绑定商户角色查询权限*/
            BspsUserRoleInfoMapper bspsUserRoleInfoMapper = new BspsUserRoleInfoMapperImpl();
            List<UserRoleInfo> userRoleInfoList = bspsUserRoleInfoMapper.selectBspsUserRoleInfoToChannelMenu(mchntBindInfo.getInstId(), mchntBindInfo.getBindUserRole(), channelId);
            /*角色权限赋值*/
            List<PrivilegeInfoBean> privilegeInfoList = new ArrayList<>();
            if (null != userRoleInfoList && !userRoleInfoList.isEmpty()) {
                userRoleInfoList.forEach(item -> convUserRoleInfo(item, privilegeInfoList));
            }
            mchntBindInfoBean.setPrivilegeInfoBeanList(privilegeInfoList);
            mchntBindInfoList.add(mchntBindInfoBean);
        } catch (Exception e) {
            ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
            e.printStackTrace(new PrintWriter(byteArrayOutputStream, true));
            rglog.error("根据角色标识<{}>获取用户角色信息异常,异常信息:<{}>", mchntBindInfo.getBindUserRole(), byteArrayOutputStream.toString());
            throw new BizException(RespCodeEnum.GET_USER_ROLE_INFO_ERROR.getRespCode(), RespCodeEnum.GET_USER_ROLE_INFO_ERROR.getRespDesc());
        }
    }

    /*用户权限信息装换、
     * userRoleInfo 用户权限信息
     * */
    private void convUserRoleInfo(UserRoleInfo userRoleInfo, List<PrivilegeInfoBean> privilegeInfoList) {
        PrivilegeInfoBean privilegeInfo = new PrivilegeInfoBean();
        /*菜单标识赋值*/
        privilegeInfo.setMenuId(userRoleInfo.getMenuId());
        /*菜单名称赋值*/
        privilegeInfo.setMenuName(userRoleInfo.getMenuName());
        /*功能权限标识*/
        privilegeInfo.setFuncDroitId(userRoleInfo.getFuncDroitId());
        /*功能权限名称赋值*/
        privilegeInfo.setFuncDroitDesc(userRoleInfo.getFuncDroitDesc());
        /*菜单页面路径赋值*/
        privilegeInfo.setMenuUrlPath(userRoleInfo.getMenuUrlPath());
        /* 上级菜单 */
        privilegeInfo.setSuperMenuId(userRoleInfo.getSuperMenuId());
        /* 菜单是否隐藏标识 */
        privilegeInfo.setMenuHideFlag(userRoleInfo.getMenuHideFlag());
        BeanUtil.beanCopy(userRoleInfo, privilegeInfo);
        privilegeInfoList.add(privilegeInfo);
    }

    @Override
    protected void bizAfterCust(Object response) throws Exception {
        BizResponse bizResponse = (BizResponse) response;
        LoginOrderStatusQueryResponse loginOrderStatusQueryResponse = (LoginOrderStatusQueryResponse) bizResponse.getResult();
        ConvertUtil.convertInput(loginOrderStatusQueryResponse);
    }
}
